package com.homework.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

@Aspect
@Component
@Slf4j
public class TestLogAspect {
    // part1: pointCut for join-points
    @Pointcut("execution(* com.homework.dao..*.*(..))")
    public void allDaoMethods(){}

    // part 2:  advice -> enhancing / adding functionals
    @Around("allDaoMethods()")
    public Object timeMeasureForAllMethods(ProceedingJoinPoint pjp) {
        long start = System.currentTimeMillis() ;
        Object res = null ;
        try {
            // here, before-logic could be added .
            log.info("test log aspect info BEFORE method: {}",
                    pjp.getSignature().getName()) ;
            res = pjp.proceed();  // userDao.insert(user)
            // here, after-logic could be added too.
            log.info("test log aspect info AFTER method: {}, spent: {} s",
                    pjp.getSignature().getName(), (System.currentTimeMillis() - start) / 1000.0) ;
        } catch (Throwable e) {
            log.error("error from test log aspect for method-{}: {}",
                    pjp.getSignature().getName(), e.getMessage());
        }
        return res ;

    }

    @Before("allDaoMethods()")
    public void checkNullableForDaoMethods(JoinPoint jp) {
        /**
         * check the not-null for all args of related methods
         *
         */
        Object[] args = jp.getArgs() ;
        if (ObjectUtils.isEmpty(args)) {
            log.error("info from test-log-aspect:{} with null args!", jp.getSignature().getName()) ;
            return ;
        }
        log.info("info from test-log-aspect:{} with not-null args!", jp.getSignature().getName()) ;

    }


}